package net.sansi.v3correctserver.util;

import cn.hutool.core.util.StrUtil;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.Accessors;

/**
 * 统计分布情况工具
 */
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class Distribution {

    public Distribution(String title) {
        this.title = title;
    }

    public Distribution(String title, double[] levels) {
        this.title = title;
        this.levels = levels;
        counts = new int[levels.length + 1];
        countsNeg = new int[levels.length + 1];
    }

    private double[] levels = {0.01, 0.02, 0.03, 0.04};
    private int[] counts = {0, 0, 0, 0, 0};
    private int[] countsNeg = {0, 0, 0, 0, 0};

    @Accessors(chain = true)
    private double target = 0;
    private String title;

    public int getSum() {
        return getSum(counts);
    }

    public int getSum(int[] counts) {
        int sum = 0;
        for (int c : counts) sum += c;
        return sum;
    }

    public void add(double v) {
        double p = (v - target) / Math.min(v, target);
        addPercent(p);
    }

    public void addPercent(double p) {
        for (int i = 0; i < levels.length; i++) {
            if (Math.abs(p) <= levels[i]) {
                counts[i]++;
                if (p < 0) countsNeg[i]++;
                return;
            }
        }
        counts[levels.length]++;
        if (p < 0) countsNeg[levels.length]++;
    }

    public double toPercent(int count) {
        return toPercent(count, counts);
    }

    public double toPercent(int count, int[] counts) {
        return Math.round(count * 10000.0 / getSum(counts)) / 100.0;
    }

    public int[] getPCounts() {
        int[] pc = new int[counts.length];
        for (int i = 0; i < pc.length; i++) {
            pc[i] = counts[i] - countsNeg[i];
        }
        return pc;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("[离散情况统计] " + title);
        int[][] cts = new int[][]{
                counts,
                getPCounts(),
                countsNeg,
        };
        String[] title = new String[]{
                "ALL", "过调", "欠调"
        };
        for (int c = 0; c < 3; c++) {
            int[] counts = cts[c];
            sb.append("\n");
            sb.append(StrUtil.format("[{} : {}] ",
                    title[c], getSum(counts)
            ));
            for (int i = 0; i < levels.length; i++) {
                String level = levels[i] * 100 + "%";
                sb.append(StrUtil.format("{}:{}({}%),", level, counts[i], toPercent(counts[i], counts)));
                if (i + 1 == levels.length) {
                    sb.append(StrUtil.format("gt{}:{}({}%),", level, counts[i + 1], toPercent(counts[i + 1], counts)));
                }
            }
        }
        return sb.toString();
    }

}